package com.moarea.app.util;

import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/*
 * 编码生成工具类
 * @author dave_xu
 * @version 2017-9-29
 * */
public class CreateCodeUtils {


    /**
     * 生成8位随机数
     *
     * @param str
     * @param n
     * @param m
     * @param set
     */
    public static void randomSetNew(StringBuilder str, int n, int m, HashSet<String> set) {
        DecimalFormat mFormat = new DecimalFormat("00000000");
        for (int i = 0; i < n; i++) {
            int num = (int) (Math.random() * 100000000);
            set.add(str.toString() + mFormat.format(num));// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSetNew(str, n - setSize, m, set);// 递归
        }
    }

    /**
     * 生成7位随机数
     *
     * @param str
     * @param n
     * @param m
     * @param set
     */
    public static void randomSet(StringBuilder str, int n, int m, HashSet<String> set) {
        DecimalFormat mFormat = new DecimalFormat("0000000");
        for (int i = 0; i < n; i++) {
            int num = (int) (Math.random() * 10000000);
            set.add(str.toString() + mFormat.format(num));// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSet(str, n - setSize, m, set);// 递归
        }
    }

    public static void randomSet2(StringBuilder str, int n, int m, HashSet<String> set) {
        DecimalFormat mFormat = new DecimalFormat("0000000");
        Random random = new SecureRandom();
        for (int i = 0; i < n; i++) {
            int num = random.nextInt(10000000);
            set.add(mFormat.format(num));// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSet2(str, n - setSize, m, set);// 递归
        }
    }

    public static void randomSet3(StringBuilder str, int n, int m, HashSet<Integer> set) {
        // DecimalFormat mFormat = new DecimalFormat("0000000");
        Random random = new SecureRandom();
        for (int i = 0; i < n; i++) {
//            int num = (int) (Math.random() * 10000000);
            int num = random.nextInt(10000000);
            // set.add(num);// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
//        if (setSize < m) {
//            randomSet3( str,n - setSize,m, set);// 递归
//        }
    }

    public static void randomSet4(int n, int m, HashSet<Integer> set) {
        // DecimalFormat mFormat = new DecimalFormat("0000000");
        Random random = new SecureRandom();
        for (int i = 0; i < n; i++) {
//            int num = (int) (Math.random() * 10000000);
            int num = random.nextInt(10000000);
            set.add(num);// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        System.out.println(setSize);
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSet4(n - setSize, m, set);// 递归
        }
    }

    public static void randomSetByThreadLoaclRanom(int n, int m, HashSet<Integer> set) {
        DecimalFormat mFormat = new DecimalFormat("0000000");
        ThreadLocalRandom.current();
        for (int i = 0; i < n; i++) {
//            int num = (int) (Math.random() * 10000000);
            // int num=random.nextInt(10000000);

            int num = ThreadLocalRandom.current().nextInt(10000000);
            set.add(num);// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        System.out.println(setSize);
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSetByThreadLoaclRanom(n - setSize, m, set);// 递归
        }
    }

    public static void randomSetByThreadLoaclRandomStr(String str, int n, int m, HashSet<String> set, int len) {
        DecimalFormat mFormat = new DecimalFormat(generateDecimalFormat(len));
        for (int i = 0; i < n; i++) {
            int num = ThreadLocalRandom.current().nextInt((int) Math.pow(10, len));
            set.add(str + mFormat.format(num));// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        System.out.println(setSize);
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < m) {
            randomSetByThreadLoaclRandomStr(str, n - setSize, m, set, len);// 递归
        }
    }

    public static void randomSetByThreadLoaclRandomStr2(String str, int n, HashSet<String> set, int len) {
        DecimalFormat mFormat = new DecimalFormat(generateDecimalFormat(len));
        for (int i = 0; i < n; i++) {
            int num = ThreadLocalRandom.current().nextInt((int) Math.pow(10, len));
            set.add(str + mFormat.format(num));// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        System.out.println(setSize);
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
    }


    public static void createCode(String str, HashSet<String> set, int all, int per, int len) {
        int count = all / per;
        if (count == 0) {
            randomSetByThreadLoaclRandomStr(str, all, all, set, len);
        } else {
            for (int i = 0; i < count; i++) {
                randomSetByThreadLoaclRandomStr2(str, per, set, len);
            }
            int residual = all - count * per;
            randomSetByThreadLoaclRandomStr2(str, residual, set, len);
        }
        while (set.size() < all) {
            int last = all - set.size();
            randomSetByThreadLoaclRandomStr2(str, last, set, len);
        }
    }

    private static String generateDecimalFormat(int len) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < len; i++) {
            builder.append("0");
        }
        return builder.toString();
    }
}
